home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / plot3d / DensView.m < prev    next >
Encoding:
Text File  |  1992-08-17  |  4.9 KB  |  187 lines

  1. /* DensView.m  Copyright 1992 Steve Ludtke */
  2.  
  3. /* This object works by taking passed data and rendering it into an NXImage */
  4. /* which is then composited to the screen as necessary. When the view is    */
  5. /* resized, the user coordinate system is reset to unit size. Areas can be  */ 
  6. /* selected by dragging with the mouse. A zoomTo:::: message will be sent to*/ 
  7. /* the delegate with the resulting area. */
  8.  
  9. #import "Plot3DView.h"
  10. #import "DensView.h"
  11.  
  12. #import <stdio.h>
  13. #import <string.h>
  14. #import <libc.h>
  15. #import <math.h>
  16. #import <appkit/NXImage.h>
  17. #import <appkit/OpenPanel.h>
  18. #import <appkit/Slider.h>
  19. #import <dpsclient/psops.h>
  20. #import <appkit/Application.h>
  21.  
  22. char hex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
  23.  
  24. extern id NXApp;
  25.  
  26. @implementation DensView
  27.  
  28. -initFrame:(NXRect *)myrect
  29. {
  30. [super initFrame:myrect];
  31. [self setDrawSize:1.0 :1.0];    /* set size and origin so view is a "unit" */
  32. [self setDrawOrigin:0.0 :0.0];    /* coordinate system */
  33. point.y=point.x=0.0;        /* origin of image when composited */
  34. buf=NULL;
  35. data=NULL;
  36. image=nil;            /* new image is created by -setData::::: */
  37. return self;
  38. }
  39.  
  40. -superviewSizeChanged:(const NXSize *)oldsize
  41. {
  42. [super superviewSizeChanged:oldsize];
  43. [self setDrawSize:1.0 :1.0];            /* fix drawing size */
  44. [self setData:nx :ny :data :minZ :maxZ];    /* re-render NXImage */
  45. return self;
  46. }
  47.  
  48. /* essentially all this method has to do is composite the NXImage to the */
  49. /* screen. */
  50. -drawSelf:(NXRect *)rects :(int)rectCount
  51. {
  52.  
  53. if (buf==NULL||data==NULL||image==nil) {
  54.     PSsetgray(NX_BLACK);
  55.     NXRectFill(&bounds);
  56.     return(self);
  57. }
  58.  
  59. [image composite:NX_COPY toPoint:&point];
  60.  
  61. return self;
  62. }
  63.  
  64. /* This method receives data and generates the NXImage */
  65. -setData:(int)Nx :(int)Ny :(float *)Data :(float)MinZ :(float)MaxZ
  66. {
  67. NXStream *str;
  68. static char s[220];
  69. int i,n,d;
  70.  
  71. /* Make sure our postscript buffer is big enough */
  72. if ((Nx*Ny)>bufs) {
  73.     if (buf!=NULL) free(buf);
  74.     buf=malloc(Nx*Ny*2+Nx*Ny/20+400);
  75.     bufs=Nx*Ny;
  76. }
  77. data=Data;
  78. nx=Nx;
  79. ny=Ny;
  80. minZ=MinZ;
  81. maxZ=MaxZ;
  82.  
  83. /* Since everything conforms properly, it would be quite easy to generate */
  84. /* an EPS file from this data ... */
  85. sprintf(s,"%%!PS-Adobe-2.0 EPSF-2.0\n%%%%Origin:0 0\n%%%%BoundingBox: 0 0 %f %f\n%%%%EndComments\n%f %f scale\n/picstr 1 string def\ngsave\n",frame.size.width,frame.size.height,frame.size.width,frame.size.height);
  86. strcpy(buf,s);
  87. sprintf(s,"%d %d 8 [%d 0 0 %d 0 0] {currentfile picstr readhexstring pop} image\n",nx,ny,nx,ny);
  88. strcat(buf,s);
  89. i=strlen(buf);
  90. for (n=0; n<(nx*ny); n++) {
  91.         if (n%100==0) buf[i++]='\n';
  92.         d=255*(data[n]-minZ)/(maxZ-minZ);
  93.         if (d>255) d=255;
  94.         if (d<0) d=0;
  95.         buf[i++]=hex[d>>4];
  96.         buf[i++]=hex[d&15];
  97. }
  98. buf[i]=0;
  99. sprintf(s,"\ngrestore\n");
  100. strcat(buf,s);
  101.  
  102. /* send the postscript we generated to an NXImage. I know this is a messy */
  103. /* way of doing things, but it's leftover from a previous incarnation of  */
  104. /* this object and I didn't feel like rewriting it ... */
  105. str=NXOpenMemory(buf,strlen(buf),NX_READONLY);
  106. if (image!=nil) [image free];
  107. image=[NXImage alloc];
  108. image=[image initFromStream:str];
  109. NXClose(str);
  110. /* This is how it used to work */
  111. /*DPSWritePostScript(DPSGetCurrentContext(), buf, i);*/
  112.  
  113. [self display];
  114. return self;
  115. }
  116.  
  117. /* Allows the user to select an area of the plot to be passed to the */
  118. /* delegate via a zoomTo:::: message. */
  119. -mouseDown:(NXEvent *)oevent 
  120. {
  121. int oldMask,loop=1;
  122. NXEvent *event,evs;
  123. float f,dash[2] = { SS,SS };
  124.  
  125. evs=*oevent;
  126. oevent=&evs;
  127. [self convertPoint:&oevent->location fromView:nil];
  128.  
  129. oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
  130.  
  131. while (loop) {
  132.     event = [NXApp getNextEvent:(NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK)];
  133.     [self convertPoint:&event->location fromView:nil];
  134.  
  135.         switch (event->type) {
  136.         case NX_LMOUSEUP:
  137.                 loop = 0;
  138.         if (event->location.x<oevent->location.x) {
  139.             f=event->location.x;
  140.             event->location.x=oevent->location.x; 
  141.             oevent->location.x=f; 
  142.         }
  143.         if (event->location.y<oevent->location.y) {
  144.             f=event->location.y;
  145.             event->location.y=oevent->location.y; 
  146.             oevent->location.y=f; 
  147.         }
  148.         if (event->location.x-oevent->location.x<.02) break;
  149.         if (event->location.y-oevent->location.y<.02) break;
  150.         [delegate zoomTo:oevent->location.x :oevent->location.y :event->location.x :event->location.y];
  151.             break;
  152.         case NX_LMOUSEDRAGGED:
  153.         [self lockFocus];
  154.         PSsetlinewidth(0.0);
  155.         [image composite:NX_COPY toPoint:&point];
  156.  
  157.         PSmoveto(oevent->location.x,oevent->location.y);
  158.         PSlineto(event->location.x,oevent->location.y);
  159.         PSlineto(event->location.x,event->location.y);
  160.         PSlineto(oevent->location.x,event->location.y);
  161.         PSlineto(oevent->location.x,oevent->location.y);
  162.  
  163.         PSsetgray(1.0);
  164.         PSsetdash(dash,2,0.0);
  165.         PSgsave();
  166.         PSstroke();
  167.         PSgrestore();
  168.  
  169.         PSsetgray(0.0);
  170.         PSsetdash(dash,2,SS);
  171.         PSstroke();
  172.  
  173.         [self unlockFocus];
  174.         [window flushWindow];
  175.         break;
  176.     }
  177.     
  178. }
  179. [window setEventMask:oldMask];
  180. return self;
  181. }
  182.  
  183. -(int)acceptsFirstMouse {
  184. return (YES);
  185. }
  186. @end
  187.